import { _decorator } from 'cc';

export default class Suan24Dian_GameManager {
    //    // 分数类
    static Fraction = class {
        numerator: number;
        denominator: number;
        constructor(numerator: number, denominator: number = 1) {
            if (denominator === 0) throw new Error("分母不能为0");
            const gcdValue = Suan24Dian_GameManager.gcd(Math.abs(numerator), Math.abs(denominator));
            this.numerator = numerator / gcdValue;
            this.denominator = denominator / gcdValue;

            if (this.denominator < 0) {
                this.numerator *= -1;
                this.denominator *= -1;
            }
        }
        add(f: typeof Suan24Dian_GameManager["Fraction"]): typeof Suan24Dian_GameManager["Fraction"] {
            return new Suan24Dian_GameManager.Fraction(

                this.numerator * f.denominator + f.numerator * this.denominator,
                this.denominator * f.denominator
            );
        }
        sub(f: Suan24Dian_GameManager.Fraction): Suan24Dian_GameManager.Fraction {
            return new Suan24Dian_GameManager.Fraction(
                this.numerator * f.denominator - f.numerator * this.denominator,
                this.denominator * f.denominator
            );
        }
        mul(f: Suan24Dian_GameManager.Fraction): Suan24Dian_GameManager.Fraction {
            return new Suan24Dian_GameManager.Fraction(
                this.numerator * f.numerator,
                this.denominator * f.denominator
            );
        }
        div(f: Suan24Dian_GameManager.Fraction): Suan24Dian_GameManager.Fraction {
            if (f.numerator === 0) throw new Error("除以0");
            return new Suan24Dian_GameManager.Fraction(
                this.numerator * f.denominator,
                this.denominator * f.numerator
            );
        }
        equals(n: number): boolean {
            return this.numerator === n * this.denominator;
        }
        toNumber(): number {
            return this.numerator / this.denominator;
        }
        toString(): string {
            if (this.denominator === 1) {
                return this.numerator.toString();
            }
            return `${this.numerator}/${this.denominator}`;
        }
    };
    //    // 计算最大公约数
    static gcd(a: number, b: number): number {
        a = Math.abs(a);
        b = Math.abs(b);
        while (b > 0) {
            let temp = b;
            b = a % b;
            a = temp;
        }
        return a;
    }
    static getAllSolutions(nums: number[]): string[] {
        const target = 24;
        const results = new Set<string>();
        const fractions = nums.map(n => new Suan24Dian_GameManager.Fraction(n));
        const exprs = nums.map(n => n.toString());

        function helper(fs: Suan24Dian_GameManager.Fraction[], es: string[]): void {
            if (fs.length === 1) {
                if (fs[0].equals(target)) {
                    // 移除最外层括号
                    let solution = es[0];
                    if (solution.startsWith('(') && solution.endsWith(')')) {
                        solution = solution.substring(1, solution.length - 1);
                    }
                    results.add(solution);
                }
                return;
            }

            for (let i = 0; i < fs.length; i++) {
                for (let j = 0; j < fs.length; j++) {
                    if (i === j) continue;

                    const restFs = fs.filter((_, idx) => idx !== i && idx !== j);
                    const restEs = es.filter((_, idx) => idx !== i && idx !== j);

                    const a = fs[i];
                    const b = fs[j];
                    const ea = es[i];
                    const eb = es[j];

                    // 加法
                    const addResult = a.add(b);
                    helper([addResult, ...restFs], [`(${ea}+${eb})`, ...restEs]);

                    // 减法
                    const subResult = a.sub(b);
                    helper([subResult, ...restFs], [`(${ea}-${eb})`, ...restEs]);

                    // 乘法
                    const mulResult = a.mul(b);
                    helper([mulResult, ...restFs], [`(${ea}*${eb})`, ...restEs]);

                    // 除法
                    try {
                        const divResult = a.div(b);
                        helper([divResult, ...restFs], [`(${ea}/${eb})`, ...restEs]);
                    } catch { }
                }
            }
        }

        helper(fractions, exprs);
        return Array.from(results);
    }
    //    // // 检查玩家输入表达式是否合法且等于24
    //    // static checkUserInput(expr: string, nums: number[]): boolean {
    //    //     let used = nums.slice();
    //    //     let matches = expr.match(/\d+/g);
    //    //     if (!matches) return false;
    //    //     for (let m of matches) {
    //    //         let idx = used.indexOf(Number(m));
    //    //         if (idx === -1) return false;
    //    //         used.splice(idx, 1);
    //    //     }
    //    //     try {
    //    //         // eslint-disable-next-line no-eval
    //    //         let result = eval(expr);
    //    //         return Math.abs(result - 24) < 1e-6;
    //    //     } catch {
    //    //         return false;
    //    //     }
    //    // }
    //    // // 将小数转换为分数
    //    // static decimalToFraction(num: number): string {
    //    //     const EPSILON = 1e-6;
    //    //     // 检查是否为整数
    //    //     if (Math.abs(num - Math.round(num)) < EPSILON) {
    //    //         return Math.round(num).toString();
    //    //     }
    //    //     // 处理小数
    //    //     let denominator = 1;
    //    //     while (Math.abs(num * denominator - Math.round(num * denominator)) > EPSILON) {
    //    //         denominator *= 10;
    //    //     }
    //    //     let numerator = Math.round(num * denominator);
    //    //     const commonDivisor = this.gcd(numerator, denominator);
    //    //     numerator /= commonDivisor;
    //    //     denominator /= commonDivisor;
    //    //     return `${numerator}/${denominator}`;
    //    // }
    //    // // 格式化数字，小数用分数表示
    //    // static formatNumber(num: number): string {
    //    //     const EPSILON = 1e-6;
    //    //     // 如果是整数，不显示分数部分
    //    //     if (Math.abs(num - Math.round(num)) < EPSILON) {
    //    //         return Math.round(num).toString();
    //    //     }
    //    //     // 否则转换为分数
    //    //     return this.decimalToFraction(num);
    //    // }
    //    // // 随机生成4个1~10的整数
    //    // static randomNumbers(): number[] {
    //    //     let arr = [];
    //    //     for (let i = 0; i < 4; i++) {
    //    //         arr.push(Math.floor(Math.random() * 10) + 1);
    //    //     }
    //    //     return arr;
    //    // }
    //    // // 随机生成有解的4个数
    //    // static randomNumbersWithSolution(): number[] {
    //    //     let nums: number[];
    //    //     do {
    //    //         nums = [];
    //    //         for (let i = 0; i < 4; i++) {
    //    //             nums.push(Math.floor(Math.random() * 10) + 1);
    //    //         }
    //    //     } while (!this.judgePoint24(nums));
    //    //     return nums;
    //    // }
    //    // // 判断4个数能否算出24
    //    // static judgePoint24(nums: number[]): boolean {
    //    //     const target = 24;
    //    //     const fractions = nums.map(n => new Suan24Dian_GameManager.Fraction(n));
    //    //     function helper(fs: Suan24Dian_GameManager.Fraction[]): boolean {
    //    //         if (fs.length === 1) {
    //    //             return fs[0].equals(target);
    //    //         }
    //    //         for (let i = 0; i < fs.length; i++) {
    //    //             for (let j = 0; j < fs.length; j++) {
    //    //                 if (i === j) continue;
    //    //                 const rest = fs.filter((_, idx) => idx !== i && idx !== j);
    //    //                 const a = fs[i];
    //    //                 const b = fs[j];
    //    //                 // 加法
    //    //                 const addResult = a.add(b);
    //    //                 if (helper([addResult, ...rest])) return true;
    //    //                 // 减法
    //    //                 const subResult = a.sub(b);
    //    //                 if (helper([subResult, ...rest])) return true;
    //    //                 // 乘法
    //    //                 const mulResult = a.mul(b);
    //    //                 if (helper([mulResult, ...rest])) return true;
    //    //                 // 除法
    //    //                 try {
    //    //                     const divResult = a.div(b);
    //    //                     if (helper([divResult, ...rest])) return true;
    //    //                 } catch {}
    //    //             }
    //    //         }
    //    //         return false;
    //    //     }
    //    //     return helper(fractions);
}
